//
//  main.m
//  08-iOS9新特性
//
//  Created by 402030900@qq.com on 16/7/13.
//  Copyright © 2016年 402030900@qq.com. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Pserson.h"
#import "Truck.h"
#import "Student.h"
int main(int argc, const char * argv[]) {
    Pserson * person = [[Pserson alloc]init];
    //a
    // nonull 修饰的属性 对应的getter 和 setter方法
    NSString * objc = nil;
    person.name = objc;
    [person setName:objc];
    person.name = @"张三";
    [person name];
    
    // nullable 修饰的属性,对应的getter和setter方法
    // [person setSex:<#(NSString * _Nullable)#>];
    // [person sex];
    person.sex = nil;
    
    // null_resetable:
    // [person setFriends:<#(NSArray * _Nullable)#>];
    // [person friends];
//    [person setDic:<#(NSMutableDictionary * _Nonnull)#>];
    
    //泛型
    // 带泛型的容器(规定了容器中所存储的类型)
    // 带泛型的数组
    // 声明一个可变数组,内部存放的都是NSString
    // 1.数组中添加其他类型,会有警告
    // 2.数组取出来的类型不再是id类型,对应变成声明时的类型
    // 3.泛型会改变类的一些方法,使与声明的类型相同
    NSMutableArray<NSString *> * array = [NSMutableArray arrayWithObjects:@"123", nil];
    NSMutableArray * array1 = [NSMutableArray array];
    NSString * string = array.firstObject;
//    array.firstObject.length
    [array.firstObject length];
    [array addObject:@""];
//    [array addObject:@20];
//    [array addObject:person];
//    [array addObject:<#(nonnull NSString *)#>];
//    [array1 addObject:<#(nonnull id)#>]
   NSInteger integer =  [array objectAtIndex:0].length;
    
    // 带泛型的字典
    NSMutableDictionary<NSString *,NSString *> * dic = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"余翰",@"name", nil];
    [dic objectForKey:@"name"].length;
//    [dic setObject:<#(nonnull NSString *)#> forKey:<#(nonnull id<NSCopying>)#>]
    
    //自定义泛型
    Truck<Pserson *> * truck = [[Truck alloc]init];
    [truck addObject:person];
    [truck firstObject];
    Student * stu = [[Student alloc]init];
    stu.stuNumber = @"0001";
    Truck<Student *> * truckStu = [[Truck alloc]init];
    [truck addObject:stu];
    [truckStu addObject:person];
   
    // 协变性 与 逆变性
    Truck * truck0 = nil;
    Truck<NSArray *> *truck1 = nil;
    Truck<NSMutableArray *> *truck2 = nil;
    // 大类型(任意类型)可以给有泛型的赋值
    // 也可以有泛型的给他赋值
    truck0 = truck1;
    truck0 = truck2;
    truck1 = truck0;
    truck2 = truck0;
    // __covariant 协变性 子类在给父类赋值时,自动强转
    //Truck<NSArray*> Truck<NSMutableArray*>
    truck1 = truck2;
    //__contravariant 逆变性 父类给子类赋值,自动强转(暂时不知道应用何处)
    truck2 = truck1;
    //3.__kindOf
    //加__kindof修饰后,返回的类型及其子类型,都可以接收这个返回值
    Truck * truckKindOf = [[Truck alloc]init];
    NSMutableArray * arr = [truckKindOf returnArray];
    NSArray * arr1 = [truckKindOf returnArray];
    NSMutableArray * arr2 = (NSMutableArray *)arr1;
    return 0;
}
